package com.kye.express.business.order.scan_code_addresses;

import com.kye.base.Logger;
import com.kye.express.contract.base.BasePresenter;
import com.kye.express.contract.base.view.ErrorView;
import com.kye.express.contract.base.view.IView;
import com.kye.express.contract.base.view.LoadingView;
import com.kye.model.OpenApiResultObserver;
import com.kye.model.bean.OpenApiResult;
import com.kye.model.bean.order.scan_code_order.ScanCodeOrderAddress;
import com.kye.model.datasource.OrderDataSource;
import com.kye.model.gson_adapter.ApiException;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.SingleObserver;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;

import static com.kye.express.business.order.scan_code_addresses.ScanCodeAddressListActivity.SEND_ADDRESS;

public interface ScanCodeAddressListContract {
    interface ScanCodeAddressListView extends IView, LoadingView, ErrorView {

        void onAddressList(List<ScanCodeOrderAddress> addressData);
    }

    class ScanCodeAddressListPresenter extends BasePresenter<ScanCodeAddressListView> {

        private OrderDataSource mOrderDataSource;
        private int mFilterFlag;

        @Override
        public void bind(ScanCodeAddressListView view) {
            super.bind(view);
            mOrderDataSource = new OrderDataSource();
        }

        public void setAddressType(String addressType) {
            mFilterFlag = SEND_ADDRESS.equals(addressType) ? 1 : 2;
        }

        public void getAddressList() {
            mOrderDataSource.getScanCodeAddress()
                    .toObservable()
                    .flatMapIterable(new Function<OpenApiResult<List<ScanCodeOrderAddress>>, Iterable<ScanCodeOrderAddress>>() {
                        @Override
                        public Iterable<ScanCodeOrderAddress> apply(OpenApiResult<List<ScanCodeOrderAddress>> listOpenApiResult) throws Exception {
                            return listOpenApiResult.getData();
                        }
                    })
                    .filter(new Predicate<ScanCodeOrderAddress>() {
                        @Override
                        public boolean test(ScanCodeOrderAddress addressData) throws Exception {
                            return addressData.getFlag() == mFilterFlag;
                        }
                    })
                    .toList()
                    .onErrorReturnItem(new ArrayList<>())
                    .compose(getView().bindToLifecycleDestroy())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new SingleObserver<List<ScanCodeOrderAddress>>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            getView().onLoading();
                        }

                        @Override
                        public void onSuccess(List<ScanCodeOrderAddress> addressData) {
                            getView().onLoaded();
                            getView().onAddressList(addressData);
                        }

                        @Override
                        public void onError(Throwable e) {
                            Logger.e(e, "getAddressList");

                            getView().onLoaded();
                            if (e instanceof ApiException) {
                                getView().onError(((ApiException) e).getOpenApiResult().getMsg());
                            } else {
                                getView().onError();
                            }
                        }
                    });
        }

        public void deleteAddress(String guid) {
            mOrderDataSource.deleteScanCodeAddress(guid)
                    .compose(getView().bindToLifecycleDestroy())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<Object>() {
                        @Override
                        public void onLoading(Disposable d) {
                            getView().onLoading();
                        }

                        @Override
                        public void onSuccess(OpenApiResult<Object> result, Object o) {
                            getAddressList();
                        }

                        @Override
                        public void onApiError(OpenApiResult<Object> result, int code, String msg) {
                            getView().onError(msg);
                        }

                        @Override
                        public void onOtherError(Throwable e) {
                            getView().onError();
                        }

                        @Override
                        public void onLoaded() {
                            getView().onLoaded();
                        }
                    });
        }
    }
}
